/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package matematicadiscretaxml;

/**
 *
 * @author diego
 */
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;
import java.util.ArrayList;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.DOMImplementation;

public class XML {
    
    private String cadena_ruta = "";
    
    public XML(String _cadena_ruta)
    {
        cadena_ruta = _cadena_ruta;
    }

    public ArrayList leerXMLDiccionario()
    {
        ArrayList arreglo_dic = new ArrayList();
        try
        {
            File fXmlFile_def = new File(getCadena_ruta());

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc_def = dBuilder.parse(fXmlFile_def);

            doc_def.getDocumentElement().normalize();

            System.out.println("ELEMENTO PRINCIPAL DEFINICION :" + doc_def.getDocumentElement().getNodeName());
            NodeList nList_def = doc_def.getElementsByTagName("palabra");
            for (int i = 0; i < nList_def.getLength(); i++ )
            {
                Node nNode_def = nList_def.item(i);
                if (nNode_def.getNodeType() == Node.ELEMENT_NODE) {

                  Element eElement = (Element) nNode_def;
                  arreglo_dic.add(getTagValue("sintaxis", eElement));
//                  System.out.println("NOMBRE : " + getTagValue("nombre", eElement));
//                  System.out.println("DESCRIPCION : " + getTagValue("descripcion", eElement));

               }
            }

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return arreglo_dic;
    }

    public ArrayList leerXMLArchivos(String campo_padre, String campo_hijo)
    {
        ArrayList arreglo_dic = new ArrayList();
        try
        {
            File fXmlFile_def = new File(getCadena_ruta());

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc_def = dBuilder.parse(fXmlFile_def);

            doc_def.getDocumentElement().normalize();

            System.out.println("ELEMENTO PRINCIPAL DEFINICION :" + doc_def.getDocumentElement().getNodeName());
            NodeList nList_def = doc_def.getElementsByTagName(campo_padre);
            for (int i = 0; i < nList_def.getLength(); i++ )
            {
                Node nNode_def = nList_def.item(i);
                if (nNode_def.getNodeType() == Node.ELEMENT_NODE) {

                  Element eElement = (Element) nNode_def;
                  arreglo_dic.add(getTagValue(campo_hijo, eElement));
//                  System.out.println("NOMBRE : " + getTagValue("nombre", eElement));
//                  System.out.println("DESCRIPCION : " + getTagValue("descripcion", eElement));

               }
            }

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return arreglo_dic;
    }

    public ArrayList leerXMLArchivosCondicion(String campo_padre, String campo_hijo, String condicion)
    {
        ArrayList arreglo_dic = new ArrayList();
        try
        {
            File fXmlFile_def = new File(getCadena_ruta());

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc_def = dBuilder.parse(fXmlFile_def);

            doc_def.getDocumentElement().normalize();

            System.out.println("ELEMENTO PRINCIPAL DEFINICION :" + doc_def.getDocumentElement().getNodeName());
            NodeList nList_def = doc_def.getElementsByTagName(campo_padre);
            for (int i = 0; i < nList_def.getLength(); i++ )
            {
                Node nNode_def = nList_def.item(i);
                if (nNode_def.getNodeType() == Node.ELEMENT_NODE) {

                  Element eElement = (Element) nNode_def;
                  if(getTagValue(campo_hijo, eElement).equals(condicion))
                  {
                      arreglo_dic.add(getTagValue("tipo_dato", eElement));
                  }
                  
               }
            }

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return arreglo_dic;
    }

    /*
     * ESTE METODO RETORNA UN ARREGLO DE OBJETOS DEFINICION_TABLA
     */
    public ArrayList retornarListaCampos(String nombre_tabla)
    {
        ArrayList arreglo_def = new ArrayList();
        DefinicionTabla obj_def_tabla = new DefinicionTabla();
        try
        {
            File fXmlFile_def = new File(getCadena_ruta());

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc_def = dBuilder.parse(fXmlFile_def);

            doc_def.getDocumentElement().normalize();

            System.out.println("ELEMENTO PRINCIPAL DEFINICION :" + doc_def.getDocumentElement().getNodeName());
            NodeList nList_def = doc_def.getElementsByTagName("campo");
            for (int i = 0; i < nList_def.getLength(); i++ )
            {
                Node nNode_def = nList_def.item(i);
                if (nNode_def.getNodeType() == Node.ELEMENT_NODE)
                {
                    obj_def_tabla = new DefinicionTabla(nombre_tabla
                            , ((Element)nNode_def).getElementsByTagName("nombre").item(0).getTextContent().toString()
                            , ((Element)nNode_def).getElementsByTagName("tipo_dato").item(0).getTextContent().toString()
                            , ((Element)nNode_def).getElementsByTagName("primaria").item(0).getTextContent().toString()
                            , ((Element)nNode_def).getElementsByTagName("foranea").item(0).getTextContent().toString()
                            , ((Element)nNode_def).getElementsByTagName("tabla_referencia").item(0).getTextContent().toString());

                    arreglo_def.add(obj_def_tabla);
               }
            }

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return arreglo_def;
    }

    public ObjetoQuery[][] leerArchivosDatos(String campo_padre)
    {
        ObjetoQuery arreglo_obj_query[][] = new ObjetoQuery[0][0];

        boolean bandera = false;
        int contador_nodos = 0;

        try
        {
            File fXmlFile_def = new File(getCadena_ruta());

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc_def = dBuilder.parse(fXmlFile_def);

            doc_def.getDocumentElement().normalize();

            System.out.println("ELEMENTO PRINCIPAL DEFINICION :" + doc_def.getDocumentElement().getNodeName());
            NodeList nList_def = doc_def.getElementsByTagName(campo_padre);

            for (int i = 0; i < nList_def.getLength(); i++ )
            {
                Node nNode_def = nList_def.item(i);
                if (nNode_def.getNodeType() == Node.ELEMENT_NODE)
                {
                    Element eElement = (Element) nNode_def;
                    if(bandera == false)
                    {
                        for(int j = 0; j<nNode_def.getChildNodes().getLength(); j++)
                        {
                            if (eElement.getChildNodes().item(j).getNodeType() == Node.ELEMENT_NODE)
                            {
                                contador_nodos++;
                            }
                        }
                    }

                    int k = 0;

                    for(int j = 0; j<nNode_def.getChildNodes().getLength(); j++)
                    {
                        if (eElement.getChildNodes().item(j).getNodeType() == Node.ELEMENT_NODE)
                        {
                            if(bandera == false)
                            {
                                System.out.println("numero_NODOS: "+contador_nodos);
                                arreglo_obj_query = new ObjetoQuery[nList_def.getLength()][contador_nodos];
                                bandera = true;
                            }
                            arreglo_obj_query[i][k] = new ObjetoQuery(campo_padre.toLowerCase(), eElement.getChildNodes().item(j).getNodeName().toLowerCase()
                                                                    , getTagValue( eElement.getChildNodes().item(j).getNodeName().toLowerCase(), eElement));
                            k++;
                        }
                    }
                }
            }

            for (int i = 0; i < arreglo_obj_query.length; i++ )
            {
                for (int j = 0; j < arreglo_obj_query[0].length; j++ )
                {
                    System.out.println("TABLA: "+arreglo_obj_query[i][j].getTabla()+
                                        " | COLUMNA: "+arreglo_obj_query[i][j].getTabla()+
                                        " | "+arreglo_obj_query[i][j].getObjeto());
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        return arreglo_obj_query;
    }

    public void eliminarRegistroXML(ObjetoQuery[][] tabla_obj_query )
    {
        ObjetoQuery[][] obj_query_aux = new ObjetoQuery[1][tabla_obj_query[0].length];
        ArrayList<ObjetoQuery> lista = new ArrayList<ObjetoQuery>();
        int contador_columna = 0;
        int contador_modificados = 0;
        boolean bandera_coincidencia = true;

        try
        {
            File fXmlFile_def = new File(getCadena_ruta());

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc_def = dBuilder.parse(fXmlFile_def);

            doc_def.getDocumentElement().normalize();

//            Node registro_reemplazo;

//            NodeList nList_def = doc_def.getElementsByTagName(lista_modifica.get(0).getTabla());
            NodeList nList_def = doc_def.getElementsByTagName(tabla_obj_query[0][0].getTabla().toLowerCase());

            for(int i = 0; i < nList_def.getLength(); i++ )
            {
                NodeList lista_nodos = nList_def.item(i).getChildNodes();
                for(int j = 0; j < lista_nodos.getLength(); j++ )
                {
                    if( lista_nodos.item(j).getNodeType() == Node.ELEMENT_NODE )
                    {
                        obj_query_aux[0][contador_columna] = new ObjetoQuery(nList_def.item(i).getNodeName()
                                                                            , lista_nodos.item(j).getNodeName()
                                                                            , lista_nodos.item(j).getTextContent());
                        System.out.println("NOMBRE NODO HIJO: "+lista_nodos.item(j).getNodeName());
                        contador_columna++;
                    }
                }

                for(int m = 0; m < tabla_obj_query.length; m++ )
                {
                    for(int n = 0; n < tabla_obj_query[0].length; n++ )
                    {
                        System.out.println("CONTADOR COLUMNA: "+contador_columna+" | "+tabla_obj_query[0].length);
                        if(tabla_obj_query[m][n].getColumna().toLowerCase().equals(obj_query_aux[0][n].getColumna().toLowerCase())
                           && tabla_obj_query[m][n].getTabla().toLowerCase().equals(obj_query_aux[0][n].getTabla().toLowerCase()) )
                        {
                            if( !tabla_obj_query[m][n].getObjeto().toString().toLowerCase().equals(obj_query_aux[0][n].getObjeto().toString().toLowerCase()))
                            {
                                bandera_coincidencia = false;
                            }
                        }
                    }

                    if(bandera_coincidencia == true)
                    {
                        nList_def.item(i).getParentNode().removeChild(nList_def.item(i));
//                        registro_reemplazo = doc_def.createElement(lista_modifica.get(0).getTabla());
//                                    System.out.println("HELLO: "+lista_modifica.get(0).getTabla());
//                        for(int z = 0; z<tabla_obj_query[0].length; z++)
//                        {
//                            for(int w = 0; w<lista_modifica.size(); w++)
//                            {
//                                if( lista_modifica.get(w).getTabla().toLowerCase().equals(tabla_obj_query[0][z].getTabla())
//                                    && lista_modifica.get(w).getColumna().toLowerCase().equals(tabla_obj_query[0][z].getColumna()))
//                                {
//                                    Node nodo_aux = doc_def.createElement(lista_modifica.get(w).getColumna().toLowerCase());
//                                    nodo_aux.setTextContent(lista_modifica.get(w).getObjeto().toString());
//                                    nList_def.item(i).removeChild( (((Element)nList_def.item(i)).getElementsByTagName(tabla_obj_query[0][z].getColumna())).item(0) );
//                                    nList_def.item(i).appendChild(nodo_aux);
//                                }
//                                else
//                                {
//                                    Node nodo_aux = doc_def.createElement(tabla_obj_query[0][z].getColumna().toLowerCase());
//                                    nodo_aux.setTextContent(tabla_obj_query[m][z].getObjeto().toString());
//                                    nList_def.item(i).removeChild( (((Element)nList_def.item(i)).getElementsByTagName(tabla_obj_query[0][z].getColumna())).item(0) );
//                                    nList_def.item(i).appendChild(nodo_aux);
//                                }
//                            }
//                        }
                        contador_modificados++;
                    }
                    bandera_coincidencia = true;

                }
                contador_columna = 0;
            }

            Transformer xformer = TransformerFactory.newInstance().newTransformer();
            xformer.transform(new DOMSource(doc_def), new StreamResult(new File(getCadena_ruta())));
            System.out.println("SE INGRESO UN REGISTRO");

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }

    public void modificarRegistroXML(ObjetoQuery[][] tabla_obj_query , ArrayList<ObjetoQuery> lista_modifica)
    {
        ObjetoQuery[][] obj_query_aux = new ObjetoQuery[1][tabla_obj_query[0].length];
        ArrayList<ObjetoQuery> lista = new ArrayList<ObjetoQuery>();
        int contador_columna = 0;
        int contador_modificados = 0;
        boolean bandera_coincidencia = true;

        try
        {
            File fXmlFile_def = new File(getCadena_ruta());

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc_def = dBuilder.parse(fXmlFile_def);

            doc_def.getDocumentElement().normalize();

            Node registro_reemplazo;

            NodeList nList_def = doc_def.getElementsByTagName(lista_modifica.get(0).getTabla());

            for(int i = 0; i < nList_def.getLength(); i++ )
            {
                NodeList lista_nodos = nList_def.item(i).getChildNodes();
                for(int j = 0; j < lista_nodos.getLength(); j++ )
                {
                    if( lista_nodos.item(j).getNodeType() == Node.ELEMENT_NODE )
                    {
                        obj_query_aux[0][contador_columna] = new ObjetoQuery(nList_def.item(i).getNodeName()
                                                                            , lista_nodos.item(j).getNodeName()
                                                                            , lista_nodos.item(j).getTextContent());
                        System.out.println("NOMBRE NODO HIJO: "+lista_nodos.item(j).getNodeName());
                        contador_columna++;
                    }
                }

                for(int m = 0; m < tabla_obj_query.length; m++ )
                {
//                    if(bandera_coincidencia == true)
//                    {
                        for(int n = 0; n < tabla_obj_query[0].length; n++ )
                        {
                            System.out.println("CONTADOR COLUMNA: "+contador_columna+" | "+tabla_obj_query[0].length);
                            if(tabla_obj_query[m][n].getColumna().toLowerCase().equals(obj_query_aux[0][n].getColumna().toLowerCase())
                               && tabla_obj_query[m][n].getTabla().toLowerCase().equals(obj_query_aux[0][n].getTabla().toLowerCase()) )
                            {
                                if( !tabla_obj_query[m][n].getObjeto().toString().toLowerCase().equals(obj_query_aux[0][n].getObjeto().toString().toLowerCase()))
                                {
                                    bandera_coincidencia = false;
                                }
                            }
                        }
//                    }
                    
                    if(bandera_coincidencia == true)
                    {
                        registro_reemplazo = doc_def.createElement(lista_modifica.get(0).getTabla());
                                    System.out.println("HELLO: "+lista_modifica.get(0).getTabla());
                        for(int z = 0; z<tabla_obj_query[0].length; z++)
                        {
                            for(int w = 0; w<lista_modifica.size(); w++)
                            {
                                if( lista_modifica.get(w).getTabla().toLowerCase().equals(tabla_obj_query[0][z].getTabla())
                                    && lista_modifica.get(w).getColumna().toLowerCase().equals(tabla_obj_query[0][z].getColumna()))
                                {
                                    Node nodo_aux = doc_def.createElement(lista_modifica.get(w).getColumna().toLowerCase());
                                    nodo_aux.setTextContent(lista_modifica.get(w).getObjeto().toString());
                                    nList_def.item(i).removeChild( (((Element)nList_def.item(i)).getElementsByTagName(tabla_obj_query[0][z].getColumna())).item(0) );
                                    nList_def.item(i).appendChild(nodo_aux);
                                }
                                else
                                {
                                    Node nodo_aux = doc_def.createElement(tabla_obj_query[0][z].getColumna().toLowerCase());
                                    nodo_aux.setTextContent(tabla_obj_query[m][z].getObjeto().toString());
                                    nList_def.item(i).removeChild( (((Element)nList_def.item(i)).getElementsByTagName(tabla_obj_query[0][z].getColumna())).item(0) );
                                    nList_def.item(i).appendChild(nodo_aux);
                                }
                            }
                        }
                        contador_modificados++;
                    }
                    bandera_coincidencia = true;

                }
                contador_columna = 0;
            }

            Transformer xformer = TransformerFactory.newInstance().newTransformer();
            xformer.transform(new DOMSource(doc_def), new StreamResult(new File(getCadena_ruta())));
            System.out.println("SE INGRESO UN REGISTRO");

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }

    public void crearNuevoArchivoXML(ArrayList<DefinicionTabla> lista)
    {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try{
        DocumentBuilder builder = factory.newDocumentBuilder();
        DOMImplementation implementation = builder.getDOMImplementation();
        Document document = implementation.createDocument(null, "tabla_def", null);
        
        

        Element raiz = document.createElement("tabla");  // creamos el elemento raiz
//        Element elemento = document.createElement(lista.get(0).getNombre_tabla()); //creamos un nuevo elemento
        Element ele_nombre = document.createElement("nombre");
        Element ele_descripcion = document.createElement("descripcion");
        ele_nombre.setTextContent(lista.get(0).getNombre_tabla().toLowerCase());
        ele_descripcion.setTextContent("esta tabla guarda "+lista.get(0).getNombre_tabla().toLowerCase());
        
        raiz.appendChild(ele_nombre);
        raiz.appendChild(ele_descripcion);
        for(int i = 0; i< lista.size(); i++)
        {
            Element ele_campo = document.createElement("campo");
            
            Element ele_nombre_aux = document.createElement("nombre");
            ele_nombre_aux.setTextContent(lista.get(i).getNombre().toLowerCase());
            Element ele_tipo_dato_aux = document.createElement("tipo_dato");
            ele_tipo_dato_aux.setTextContent(lista.get(i).getTipo_dato().toLowerCase());
            Element ele_primaria_aux = document.createElement("primaria");
            ele_primaria_aux.setTextContent(lista.get(i).getPrimaria().toLowerCase());
            Element ele_foranea_aux = document.createElement("foranea");
            ele_foranea_aux.setTextContent(lista.get(i).getForanea().toLowerCase());
            Element ele_tabla_ref_aux = document.createElement("tabla_referencia");
            ele_tabla_ref_aux.setTextContent(lista.get(i).getTabla_referencia().toLowerCase());
            
            ele_campo.appendChild(ele_nombre_aux);
            ele_campo.appendChild(ele_tipo_dato_aux);
            ele_campo.appendChild(ele_primaria_aux);
            ele_campo.appendChild(ele_foranea_aux);
            ele_campo.appendChild(ele_tabla_ref_aux);
            
            raiz.appendChild(ele_campo);
        }
        
        document.setXmlVersion("1.0"); // asignamos la version de nuestro XML
        document.getDocumentElement().appendChild(raiz);  //pegamos la raiz al documento

        Source source = new DOMSource(document);
//        carchivo.LeerArchivo("archivos_usados/archivos_base_datos/archivos_definicion/resultado_def.xml");
        StreamResult result = new StreamResult(new java.io.File("archivos_usados/archivos_base_datos/archivos_definicion/"+lista.get(0).getNombre_tabla()+"_def.xml")); //nombre del archivo
//        Result console= new StreamResult(System.out);
        Transformer transformer = TransformerFactory.newInstance().newTransformer();
        transformer.transform(source, result);
        
        Document document1 = implementation.createDocument(null, "tabla_dat", null);
        Source source1 = new DOMSource(document1);
//        carchivo.LeerArchivo("archivos_usados/archivos_base_datos/archivos_definicion/resultado_def.xml");
        StreamResult result1 = new StreamResult(new java.io.File("archivos_usados/archivos_base_datos/archivos_datos/"+lista.get(0).getNombre_tabla()+"_dat.xml")); //nombre del archivo
//        Result console= new StreamResult(System.out);
        Transformer transformer1 = TransformerFactory.newInstance().newTransformer();
        transformer1.transform(source1, result1);
        
//        transformer.transform(source, console);
        }catch(Exception e){
        System.err.println("Error: "+e);
        }
    }

    public void ingresarRegistroXML(ArrayList<ObjetoQuery> lista)
    {
        try
        {
            File fXmlFile_def = new File(getCadena_ruta());

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc_def = dBuilder.parse(fXmlFile_def);

            doc_def.getDocumentElement().normalize();

            Node nuevo_registro_padre = doc_def.createElement(lista.get(0).getTabla());

            for (int i = 0; i < lista.size(); i++ )
            {
                Node nuevo_registro = doc_def.createElement(lista.get(i).getColumna());
                nuevo_registro.setTextContent(lista.get(i).getObjeto().toString());
                nuevo_registro_padre.appendChild(nuevo_registro);
            }

            doc_def.getElementsByTagName("tabla_dat").item(0).appendChild(nuevo_registro_padre);
            Transformer xformer = TransformerFactory.newInstance().newTransformer();
            xformer.transform(new DOMSource(doc_def), new StreamResult(new File(getCadena_ruta())));
            System.out.println("SE INGRESO UN REGISTRO");

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }


    public void ingresarRegistroXMLDiccionarioTablas(ArrayList<ObjetoQuery> lista)
    {
        try
        {
            File fXmlFile_def = new File(getCadena_ruta());

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc_def = dBuilder.parse(fXmlFile_def);

            doc_def.getDocumentElement().normalize();

            Node nuevo_registro_padre = doc_def.createElement(lista.get(0).getTabla());

            for (int i = 0; i < lista.size(); i++ )
            {
                Node nuevo_registro = doc_def.createElement(lista.get(i).getColumna());
                nuevo_registro.setTextContent(lista.get(i).getObjeto().toString());
                nuevo_registro_padre.appendChild(nuevo_registro);
            }

            doc_def.getElementsByTagName("tablas").item(0).appendChild(nuevo_registro_padre);
            Transformer xformer = TransformerFactory.newInstance().newTransformer();
            xformer.transform(new DOMSource(doc_def), new StreamResult(new File(getCadena_ruta())));
            System.out.println("SE INGRESO UN REGISTRO");

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

    }

    public String getTagValue(String sTag, Element eElement)
    {
	NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();

        Node nValue = (Node) nlList.item(0);

	return nValue.getNodeValue();
    }

    /**
     * @return the cadena_ruta
     */
    public String getCadena_ruta() {
        return cadena_ruta;
    }

    /**
     * @param cadena_ruta the cadena_ruta to set
     */
    public void setCadena_ruta(String cadena_ruta) {
        this.cadena_ruta = cadena_ruta;
    }

}
